package com.hiwan.platform.util;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * Datetime   ： 2016年1月7日 上午9:37:00<br>
 * Title      :  ThreadExecutorHelper.java<br>
 * Description:   线程执行工具类<br>
 * Company    :  hiwan<br>
 * @author cbj
 *
 */
public abstract class ThreadExecutorHelper {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	private static ThreadPoolExecutor threadPoolExecutor;

	private final int[] errorCount = new int[] { 0 };

	static {
		//
		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
		int corePoolSize = (Runtime.getRuntime().availableProcessors() / 2) * 25;
		int maximumPoolSize = (Runtime.getRuntime().availableProcessors() + 1) * 25;
		int keepAliveTime = 30;
		//
		threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,
				maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
	}

	// 设置重试次数 -1:代表永远重试 0:代表不重试 >=1:代表重试的次数
	private int reTryCount = 0;

	public ThreadExecutorHelper(int reTryCount) {
		this.reTryCount = reTryCount;
		if (!(reTryCount >= -1)) {
			throw new RuntimeException(
					"ThreadExecutorHelper(int reTryCount) --> reTryCount 必须大于等于[-1]");
		}
	}

	/**
	 * 执行当前线程
	 */
	public void execute() {
		try {
			threadPoolExecutor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						doJob();
					} catch (Throwable e) {
						errorCount[0] = errorCount[0] + 1;
						logger.error(StackTraceUtil.getStackTrace(e));
						if (reTryCount == -1) {
							execute();
						} else if (reTryCount == 0) {
							// do nothing
						} else if (reTryCount > 0) {
							if (errorCount[0] < reTryCount) {
								execute();
							} else {
								doException(e);
							}
						}
					}
				}
			});
		} catch (Exception ex) {
			logger.error(StackTraceUtil.getStackTrace(ex));
			doException(ex);
		}

	}

	public abstract void doJob();

	public abstract void doException(Throwable e);

	/**
	 * 
	 * Datetime   ： 2016年1月7日 上午10:59:01<br>
	 * Title      :  ThreadExecutorHelper.java<br>
	 * Description:  监控ThreadExecutor，因为执行线程为非守护线程<br>
	 * Company    :  hiwan<br>
	 * @author cbj
	 *
	 */
	public static class ThreadExecutorMonitor {

		/**
		 * 当整个应用关闭，调用此方法，详见spring配置 
		 */
		public void shutdown() {
			threadPoolExecutor.shutdown();
		}

	}

	public int getReTryCount() {
		return reTryCount;
	}
}
